home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / gnustuff / tos / g__~1 / gplibs17.zoo / xcursesw.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-02  |  6.0 KB  |  285 lines

  1. /* 
  2. Copyright (C) 1989, 1992 Free Software Foundation
  3.     written by Eric Newton (newton@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef __GNUG__
  18. #pragma implementation
  19. #endif
  20. #include <stdio.h>
  21. #include <stdarg.h>
  22. #include <builtin.h>
  23. #include <values.h>
  24. #ifndef _OLD_STREAMS
  25. #include <strstream.h>
  26. #include <ioprivate.h>
  27. #endif
  28. // Include CurseW.h and/or curses.h *after* iostream includes,
  29. // because curses.h defines a clear macro that conflicts with iostream. Sigh.
  30. #include <xcursesw.h>
  31.  
  32. #if _G_HAVE_CURSES
  33.  
  34. int CursesWindow::count = 0;
  35.  
  36. /*
  37.  * C++ interface to curses library.
  38.  *
  39.  */
  40.  
  41. /*
  42.  * varargs functions are handled conservatively:
  43.  * They interface directly into the underlying 
  44.  * _doscan, _doprnt and/or vfprintf routines rather than
  45.  * assume that such things are handled compatibly in the curses library
  46.  */
  47.  
  48. int CursesWindow::scanw(const char * fmt, ...)
  49. {
  50.   va_list args;
  51.   va_start(args, fmt);
  52. #ifdef VMS
  53.   int result = wscanw(w , fmt , args);
  54. #else /* NOT VMS */
  55.   char buf[BUFSIZ];
  56.   int result = wgetstr(w, buf);
  57.   if (result == OK) {
  58. #ifndef _OLD_STREAMS
  59.     strstreambuf ss(buf, BUFSIZ);
  60.     result = ss.vscan(fmt, args);
  61. #else /* _OLD_STREAMS */
  62. #ifndef HAVE_VSCANF
  63.       FILE b;
  64.       b._flag = _IOREAD|_IOSTRG;
  65.       b._base = buf;
  66.       b._ptr = buf;
  67.       b._cnt = BUFSIZ;
  68.       result = _doscan(&b, fmt, args);
  69. #else /* HAVE_VSCANF */
  70.       result = vsscanf(buf, fmt, args);
  71. #endif /* HAVE_VSCANF */
  72. #endif /* _OLD_STREAMS */
  73.   }
  74. #endif /* !VMS */
  75.   va_end(args);
  76.   return result;
  77. }
  78.  
  79. int CursesWindow::mvscanw(int y, int x, const char * fmt, ...)
  80. {
  81.   va_list args;
  82.   va_start(args, fmt);
  83.   char buf[BUFSIZ];
  84.   int result = wmove(w, y, x);
  85.   if (result == OK)
  86. #ifdef VMS
  87.   result=wscanw(w , fmt , args);
  88. #else /* !VMS */
  89.  {
  90.     result = wgetstr(w, buf);
  91.     if (result == OK) {
  92. #ifndef _OLD_STREAMS
  93.     strstreambuf ss(buf, BUFSIZ);
  94.     result = ss.vscan(fmt, args);
  95. #else /* OLD_STREAMS */
  96. #ifndef HAVE_VSCANF
  97.     FILE b;
  98.     b._flag = _IOREAD|_IOSTRG;
  99.     b._base = buf;
  100.     b._ptr = buf;
  101.     b._cnt = BUFSIZ;
  102.     result = _doscan(&b, fmt, args);
  103. #else
  104.     result = vsscanf(buf, fmt, args);
  105. #endif
  106. #endif /* OLD_STREAMS */
  107.   }
  108.   }
  109. #endif /* !VMS */
  110.   va_end(args);
  111.   return result;
  112. }
  113.  
  114. int CursesWindow::printw(const char * fmt, ...)
  115. {
  116.   va_list args;
  117.   va_start(args, fmt);
  118.   char buf[BUFSIZ];
  119. #ifndef _OLD_STREAMS
  120.   strstreambuf ss(buf, BUFSIZ);
  121.   ss.vform(fmt, args);
  122.   ss.sputc(0);
  123. #else /* _OLD_STREAMS */
  124. #ifndef HAVE_VPRINTF
  125.   FILE b;
  126.   b._flag = _IOWRT|_IOSTRG;
  127.   b._ptr = buf;
  128.   b._cnt = BUFSIZ;
  129.   _doprnt(fmt, args, &b);
  130.   putc('\0', &b);
  131. #else
  132.   vsprintf(buf, fmt, args);
  133. #endif
  134. #endif /* _OLD_STREAMS */
  135.   va_end(args);
  136.   return waddstr(w, buf);
  137. }
  138.  
  139.  
  140. int CursesWindow::mvprintw(int y, int x, const char * fmt, ...)
  141. {
  142.   va_list args;
  143.   va_start(args, fmt);
  144.   int result = wmove(w, y, x);
  145.   if (result == OK)
  146.   {
  147.     char buf[BUFSIZ];
  148. #ifndef _OLD_STREAMS
  149.     strstreambuf ss(buf, BUFSIZ);
  150.     ss.vform(fmt, args);
  151.     ss.sputc(0);
  152. #else /* _OLD_STREAMS */
  153. #ifndef HAVE_VPRINTF
  154.     FILE b;
  155.     b._flag = _IOWRT|_IOSTRG;
  156.     b._ptr = buf;
  157.     b._cnt = BUFSIZ;
  158.     _doprnt(fmt, args, &b);
  159.     putc('\0', &b);
  160. #else
  161.     vsprintf(buf, fmt, args);
  162. #endif
  163. #endif /* _OLD_STREAMS */
  164.     result = waddstr(w, buf);
  165.   }
  166.   va_end(args);
  167.   return result;
  168. }
  169.  
  170. CursesWindow::CursesWindow(int lines, int cols, int begin_y, int begin_x)
  171. {
  172.   if (count==0)
  173.     initscr();
  174.  
  175.   w = newwin(lines, cols, begin_y, begin_x);
  176.   if (w == 0)
  177.   {
  178.     (*lib_error_handler)("CursesWindow", "Cannot construct window");
  179.   }
  180.  
  181.   alloced = 1;
  182.   subwins = par = sib = 0;
  183.   count++;
  184. }
  185.  
  186. CursesWindow::CursesWindow(WINDOW* &window)
  187. {
  188.   if (count==0)
  189.     initscr();
  190.  
  191.   w = window;
  192.   alloced = 0;
  193.   subwins = par = sib = 0;
  194.   count++;
  195. }
  196.  
  197. CursesWindow::CursesWindow(CursesWindow& win, int l, int c, 
  198.                            int by, int bx, char absrel)
  199. {
  200.  
  201.   if (absrel == 'r') // relative origin
  202.   {
  203.     by += win.begy();
  204.     bx += win.begx();
  205.   }
  206.  
  207.   // Even though we treat subwindows as a tree, the standard curses
  208.   // library needs the `subwin' call to link to the root in
  209.   // order to correctly perform refreshes, etc.
  210.  
  211.   CursesWindow* root = &win;
  212.   while (root->par != 0) root = root->par;
  213.  
  214.   w = subwin(root->w, l, c, by, bx);
  215.   if (w == 0)
  216.   {
  217.     (*lib_error_handler)("CursesWindow", "Cannot construct subwindow");
  218.   }
  219.  
  220.   par = &win;
  221.   sib = win.subwins;
  222.   win.subwins = this;
  223.   subwins = 0;
  224.   alloced = 1;
  225.   count++;
  226. }
  227.  
  228.  
  229. void CursesWindow::kill_subwindows()
  230. {
  231.   for (CursesWindow* p = subwins; p != 0; p = p->sib)
  232.   {
  233.     p->kill_subwindows();
  234.     if (p->alloced)
  235.     {
  236.       if (p->w != 0)
  237.         ::delwin(p->w);
  238.       p->alloced = 0;
  239.     }
  240.     p->w = 0; // cause a run-time error if anyone attempts to use...
  241.   }
  242. }
  243.     
  244. CursesWindow::~CursesWindow() 
  245. {
  246.   kill_subwindows();
  247.  
  248.   if (par != 0)   // Snip us from the parent's list of subwindows.
  249.   {
  250.     CursesWindow * win = par->subwins;
  251.     CursesWindow * trail = 0;
  252.     for (;;)
  253.     {
  254.       if (win == 0)
  255.         break;
  256.       else if (win == this)
  257.       {
  258.         if (trail != 0)
  259.           trail->sib = win->sib;
  260.         else
  261.           par->subwins = win->sib;
  262.         break;
  263.       }
  264.       else
  265.       {
  266.         trail = win;
  267.         win = win->sib;
  268.       }
  269.     }
  270.   }
  271.  
  272.   if (alloced && w != 0) 
  273.     delwin(w);
  274.  
  275.   --count;
  276.   if (count == 0) 
  277.     endwin();
  278.   else if (count < 0) // cannot happen!
  279.   {
  280.     (*lib_error_handler)("CursesWindow", "Too many windows destroyed");
  281.   }
  282. }
  283.  
  284. #endif /* _G_HAVE_CURSES */
  285.